package com.sc.pattern.readwrite;

/**
 * Created  on 2018/1/7.
 *
 * @author sc
 */
public class ReadWriteLock {
    private int readingCounter = 0;
    private int waitingReader = 0;
    private int writingCounter = 0;
    private int waitingWriter = 0;
    private boolean preferWriter = true;
    public ReadWriteLock(){
        this(true);
    }
    public ReadWriteLock(boolean preferWriter){
        this.preferWriter = preferWriter;
    }
    public synchronized void readLock() throws InterruptedException {
        this.waitingReader++;
        try {
            while (writingCounter > 0||(preferWriter&&waitingWriter>0)) {
                this.wait();
            }
            readingCounter++;
        } finally {
            waitingReader--;
        }
    }

    public synchronized void unLockRead(){
        this.readingCounter--;
        this.notifyAll();
    }

    public synchronized void writeLock() throws InterruptedException {
        this.waitingWriter++;
        try {
            if(writingCounter>0||readingCounter>0){
                this.wait();
            }
            writingCounter++;
        }finally {
            waitingWriter--;
        }
    }

    public synchronized void unLockWrite(){
        writingCounter--;
        notifyAll();
    }
}


